package org.annoflow.policy.boundry;

import java.util.HashMap;

import org.annoflow.audit.ContextTracker;
import org.annoflow.audit.Logger;
import org.annoflow.policy.PolicyType;
import org.annoflow.policy.PolicyManager;

public class SecureClassPolicy implements PolicyType {

	@Override
	public void assess(HashMap<String, String> context) throws Exception {

	}

	@Override
	public boolean audit(Object o,String filterName, Class<?> methodOwner) {
		String caller = ContextTracker.getInstance().getCallerContext();
//		StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
//		StackTraceElement element = stackTrace[stackTrace.length - 1];

		try {
			Class<?> parentCaller = Class.forName(caller);
			PolicyType policy = PolicyManager.lookupClassPolicy(parentCaller);
				if (policy == null || !policy.equals(SecureClassPolicy.class)) {
//					StackTraceElement[] elements = Thread.currentThread().getStackTrace();
					Logger.out(filterName,methodOwner,o,"This class is being passed into an insecure class");
				}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		return false;
	}

	@Override
	public String getPolicyCode() {
		return "org.annoflow.policy.boundry.SecureClassPolicy.addPolicy($class);";
	}
	public static void addPolicy(Class<?> clazz)
	{
		PolicyManager.addClassPolicy(clazz, new SecureClassPolicy());
	}
	@Override
	public PolicyType generateOrigin() {
		if(isCallerSecure())
		{
			return new SecureClassPolicy();
		}
		return new InsecureClassPolicy();
	}
	private boolean isCallerSecure()
	{
		StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
		StackTraceElement element = stackTrace[4];
//		String caller = ContextTracker.getInstance().getCallerContext();
		String caller = element.getClassName();
		try {
			Class<?> parentCaller = Thread.currentThread().getContextClassLoader().loadClass(caller);
			PolicyType policy = PolicyManager.lookupClassPolicy(parentCaller);
			if (policy == null || !(policy instanceof SecureClassPolicy)) {
					return false;
				
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return true;
	}
}
